package cn.chenmixuexi.proxy;

import cn.chenmixuexi.handler.RpcResponseMessageHandler;
import cn.chenmixuexi.message.RpcRequestMessage;
import cn.chenmixuexi.protocol.SequenceIdGenerator;
import io.netty.util.concurrent.DefaultPromise;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import static cn.chenmixuexi.net.RpcClientManager.getChannel;

public class RpcProxy {
    public static <T> T getProxyService(Class<T> serviceClass){
        ClassLoader classLoader = serviceClass.getClassLoader();
        Class<?>[] interfaces = new Class[]{serviceClass};
        T o = (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                int sequenceId = SequenceIdGenerator.nextId();
                getChannel().writeAndFlush(new RpcRequestMessage(
                        sequenceId,
                        serviceClass.getName(),
                        method.getName(),
                        method.getReturnType(),
                        method.getParameterTypes(),
                        args));
                //                                                    参数是promise执行需要的线程池
                DefaultPromise<Object> promise = new DefaultPromise<>(getChannel().eventLoop());
                RpcResponseMessageHandler.PROMISES.put(sequenceId,promise);
                //等待promise结果
                promise.await();
                if(promise.isSuccess()){
                    return promise.getNow();
                }else{
                    throw new RuntimeException(promise.cause());
                }

            }
        });
        return o;
    }
}
